import React, { useState } from 'react';
import { QRCode } from 'react-qrcode-logo';
import { ApolloError } from '@apollo/client';
import {
  Box,
  Grid,
  GridItem,
  Icon,
  Input,
  MainButton as Button,
  MainButton,
  makeToast,
  Modal,
  ModalHeader,
  Text,
} from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import LinkWrapper from 'components/link-wrapper/LinkWrapper';
import { ListItem, ListItems } from 'components/list-items/ListItems';
import { SIMCARDBYSUBSCRIPTIONID } from 'graphql/queries/simcard';
import { inject } from 'mobx-react';
import { useSnackbar } from 'notistack';
import Authentication from 'store/authentication';
import {
  SimType,
  useChangeSimcardMutation,
  useRemoveSecondarySimcardMutation,
  useSecondarySimcardQuery,
  useSimcardBySubscriptionIdQuery,
} from 'typings/graphql';
import { formatNationalId, formatTel } from 'utils/helpers';
import { Trans, useTranslation } from 'utils/i18n';

import { StillingarLoader } from '../components/StillingarLoader';

interface ISimcardSettingsContainerProps {
  subscriptionId: string;
  isStaff?: boolean;
  authentication: Authentication;
  color: string;
  userName: string;
  userNationalId: string;
}

interface IAddNewSimcardProps {
  subscriptionId: string;
  onHide: () => void;
  color: string;
  isStaff?: boolean;
  type: SimType;
  userName: string;
  userNationalId: string;
}

const SimcardSettingsContainer = ({
  subscriptionId,
  isStaff,
  color,
  userName,
  userNationalId,
  authentication,
}: ISimcardSettingsContainerProps) => {
  const { t } = useTranslation('stillingar');
  const [showAddNewSimcard, setShowAddNewSimcard] = useState(false);
  const [showAddNewEsim, setShowAddNewEsim] = useState(false);
  const { enqueueSnackbar } = useSnackbar();
  const customerCanSeeEsim = !!authentication?.isAudkenni;

  const { data, error, loading } = useSimcardBySubscriptionIdQuery({
    variables: { subscriptionId },
  });

  const {
    data: secondaryData,
    error: secondaryError,
    refetch: secondaryRefetch,
  } = useSecondarySimcardQuery({
    variables: {
      input: {
        subscriptionId,
      },
    },
  });

  const simcard = data?.simcardBySubscriptionId;
  const secondarySimcard = secondaryData?.secondarySimcard;
  const [removeModal, setRemoveModal] = useState(false);
  const [removeSecondarySimcard, { loading: removeSecondaryLoading }] =
    useRemoveSecondarySimcardMutation({
      onCompleted() {
        secondaryRefetch();
        enqueueSnackbar(t('simcard.removeSecondarySuccess'), {
          variant: 'success',
        });
        setRemoveModal(false);
      },
      onError(error: ApolloError) {
        enqueueSnackbar(t('simcard.removeSecondaryError') + error.message, {
          variant: 'error',
        });
      },
    });

  const toggleChangeEsim = () => {
    setShowAddNewEsim(!showAddNewEsim);
    setShowAddNewSimcard(false);
  };

  const toggleChangeSimcard = () => {
    setShowAddNewSimcard(!showAddNewSimcard);
    setShowAddNewEsim(false);
  };

  const onCancelClick = () => {
    setRemoveModal((prev) => !prev);
  };

  const onDeactivate = async () => {
    try {
      await removeSecondarySimcard({
        variables: {
          input: {
            subscriptionId,
          },
        },
      });
    } catch (e) {
      if (e instanceof Error) {
        enqueueSnackbar(t('simcard.removeSecondaryError') + e.message, {
          variant: 'error',
        });
      }
    }
  };

  const isESim = simcard?.type === SimType.ESim;

  if (!data || error) return null;
  if (loading) return <StillingarLoader />;

  return (
    <Box>
      <Text variant="h6" paddingBottom={2}>
        {t('simcard.title')}
      </Text>
      <Text variant="pMediumRegular" paddingBottom={3}>
        {t('simcard.subtitle')}
      </Text>
      {isStaff || customerCanSeeEsim ? (
        <Grid>
          <GridItem gridColumn={{ sm: 'span4', lg: 'span6' }}>
            <Button
              colorScheme={showAddNewEsim ? 'white' : (color as MainColorType)}
              onClick={() => toggleChangeEsim()}
              text={isESim ? t('simcard.newEsimButton') : t('simcard.esimButton')}
            />
          </GridItem>
          {isStaff && (
            <GridItem gridColumn={{ sm: 'span4', lg: 'span6' }}>
              <Button
                colorScheme="white"
                onClick={() => toggleChangeSimcard()}
                text={isESim ? t('simcard.regularSimButton') : t('simcard.newSimButton')}
                icon="longArrowRight"
              />
            </GridItem>
          )}
        </Grid>
      ) : (
        <>{!isESim && <Text>{t('simcard.contact')}</Text>}</>
      )}
      {showAddNewSimcard && (
        <AddNewSimcard
          subscriptionId={subscriptionId}
          onHide={() => toggleChangeSimcard()}
          isStaff={isStaff}
          color={color}
          type={SimType.Card}
          userName={userName}
          userNationalId={userNationalId}
        />
      )}
      {showAddNewEsim && (
        <AddNewSimcard
          subscriptionId={subscriptionId}
          onHide={() => toggleChangeEsim()}
          isStaff={isStaff}
          color={color}
          type={SimType.ESim}
          userName={userName}
          userNationalId={userNationalId}
        />
      )}
      <Text variant="subtitleBold" marginTop={5}>
        {t('simcard.simInfoTitle')}
      </Text>

      {(!isESim || (isESim && !simcard?.qrString)) && (
        <>
          {isStaff && (
            <ListItems color={color}>
              {simcard?.abandoned ? (
                <>
                  <ListItem itemLabel={t('simcard.abandoned')} itemText={simcard?.iccid || ''} />
                </>
              ) : (
                <ListItem itemLabel={t('simcard.simcard')} itemText={simcard?.iccid || ''} />
              )}
            </ListItems>
          )}
          <ListItem itemLabel={t('simcard.pin')} itemText={simcard?.pin || ''} />
          <ListItem itemLabel={t('simcard.puk')} itemText={simcard?.puk || ''} />
          <ListItem itemLabel={t('simcard.imsi')} itemText={simcard?.imsi || ''} />
          <ListItem
            itemLabel={t('simcard.type')}
            itemText={t(`simcard.typeColor.${simcard?.simType}`)}
          />
          <Box
            display="flex"
            padding={{ sm: 2 }}
            dottedShadow="small"
            backgroundColor="white"
            borderColor="grey100"
            borderWidth="1px"
            borderStyle="solid"
          >
            {simcard?.simType !== 'authenticated' ? (
              <Icon color="warning" icon="checkBox" size={24} viewBox={24} />
            ) : (
              <Icon color="success" icon="checkBox" size={24} viewBox={24} />
            )}

            <Text variant="pMediumBold" marginLeft={2}>
              {t(`simcard.typeInfo.${simcard?.simType}`)}
            </Text>
          </Box>
        </>
      )}

      {isESim && simcard?.qrString && (
        <Box
          marginTop={2}
          padding={{ sm: 2 }}
          dottedShadow="small"
          backgroundColor="white"
          borderColor="grey100"
          borderWidth="1px"
          borderStyle="solid"
          display="flex"
        >
          <QRCode value={simcard?.qrString} logoImage="/assets/nova-qr-logo.png" qrStyle="dots" />
          <Box paddingLeft={2}>
            <Text variant="h6" paddingBottom={1}>
              {t('simcard.esimTitle')}
            </Text>
            <Text variant="pMediumRegular" marginBottom={1}>
              <Trans i18nKey="stillingar:simcard.esimDescription">
                Þú þarft að fara í stillingar á símanum þínum og breyta þar í eSIM. Þú getur nálgast
                aðstoð í
                <Box
                  renderAs={LinkWrapper}
                  href="https://support.nova.is/hc/is/articles/360010721878"
                  target="_blank"
                  rel="noreferrer"
                  fontWeight="bold"
                >
                  Hjálpinni
                </Box>
                hvernig þú framkvæmir þessa aðgerð.
              </Trans>
            </Text>

            <Text variant="eyebrowMedium" color={color as MainColorType}>
              {t('simcard.esimCode')} {simcard.qrString}
            </Text>
            <Box display={'flex'} flexDirection={'column'}>
              <Text variant="eyebrowMedium" color={color as MainColorType}>
                {t('simcard.esimIccid')} {simcard.iccid}
              </Text>
              <Text variant="eyebrowMedium" color={color as MainColorType}>
                {t('simcard.imsi')} {simcard.imsi}
              </Text>
            </Box>
          </Box>
        </Box>
      )}
      {secondarySimcard && !secondaryError && (
        <Box marginTop={3}>
          <Text variant="subtitleBold" marginTop={5}>
            {t('simcard.secondarySimcardInfo')}
          </Text>
          {isStaff && (
            <ListItem
              itemLabel={t('simcard.secondarySimcardNumber')}
              itemText={secondarySimcard?.msisdn || ''}
            />
          )}
          <ListItem itemLabel={t('simcard.simcard')} itemText={secondarySimcard?.iccid || ''} />
          <ListItem itemLabel={t('simcard.imsi')} itemText={secondarySimcard?.imsi || ''} />
          <Box marginTop={1} width="6/12">
            <Button
              colorScheme="warning"
              onClick={() => onCancelClick()}
              text={t('simcard.deactivateSecondary')}
            />
          </Box>
        </Box>
      )}
      <Modal
        ariaLabel={t('activeContractItems.modal.ariaLabel')}
        onVisibilityChange={(isVisible) => setRemoveModal(isVisible)}
        isVisible={removeModal}
      >
        <Box display="flex" flexDirection="column" width="100%">
          <ModalHeader
            title={t('simcard.deactivateModalTitle')}
            eyebrow={t('simcard.deactivateModalEyebrow')}
            color="warning"
            icon="smartWatch"
          />
          <Box marginY={5} flexGrow={1}>
            {t('simcard.deactivateModalDescription')}
          </Box>
          <Box display="flex" flexDirection={['column', 'row', 'row']} gap={4} width="100%">
            <MainButton
              text={t('simcard.deactivateModalBack')}
              colorScheme="white"
              dottedShadow="none"
              isDisabled={removeSecondaryLoading}
              onClick={() => setRemoveModal(false)}
            />
            <MainButton
              text={t('simcard.deactivateModalConfirm')}
              colorScheme="warning"
              dottedShadow="none"
              isLoading={removeSecondaryLoading}
              onClick={() => onDeactivate()}
            />
          </Box>
        </Box>
      </Modal>
    </Box>
  );
};

const AddNewSimcard = ({
  subscriptionId,
  isStaff,
  onHide,
  type,
  color,
  userName,
  userNationalId,
}: IAddNewSimcardProps) => {
  const { t } = useTranslation('stillingar');
  const [changeSimcardMutation, { loading }] = useChangeSimcardMutation();

  const [message, setMessage] = useState('');
  const [iccid, setIccid] = useState('');
  const [salesNumber, setSalesNumber] = useState('');
  const [showIccidForm, setShowIccidForm] = useState(false);

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setMessage('');

    try {
      const { data } = await changeSimcardMutation({
        variables: {
          input: {
            type,
            subscriptionId,
            iccid,
            salesNumber,
          },
        },
        refetchQueries: [{ query: SIMCARDBYSUBSCRIPTIONID, variables: { subscriptionId } }],
      });

      if (data?.changeSimcard?.error) {
        throw new Error(data?.changeSimcard?.error.message);
      } else {
        makeToast.success(t('simcard.successMessage'), '');
        onHide();
      }
    } catch (e) {
      if (e instanceof Error) {
        makeToast.danger(e.message, '');
        setMessage(e.message);
      }
    }
  };

  if (type === SimType.ESim) {
    return (
      <Box
        marginTop={4}
        padding={{ sm: 3 }}
        dottedShadow="small"
        backgroundColor="white"
        borderColor="grey100"
        borderWidth="1px"
        borderStyle="solid"
      >
        <Text variant="eyebrowMedium" color="pink">
          {t('simcard.newEsimEyebrow')}
        </Text>

        <Text variant="h6" paddingBottom={2}>
          {t('simcard.newEsimTitle')}
        </Text>

        <Text variant="pMediumRegular" paddingBottom={2}>
          <Trans i18nKey="stillingar:simcard.newEsimDescription">
            eSIM styður ekki Rafræn skilríki. Því þarft þú að sækja Auðkennisappið og skrá þig inn
            með rafrænu skilríkjunum þínum áður en þú heldur áfram, því um leið og þú ferð í næsta
            skref óvirkjast símkortið og þar með rafrænu skilríkin þín á meðan við útbúum QR kóðann!
            <Box
              renderAs={LinkWrapper}
              href="https://support.nova.is/hc/is/articles/9626990235153"
              target="_blank"
              rel="noreferrer"
              fontWeight="bold"
            >
              Kynntu þér vel hvaða þjónustur styðja Auðkennisappið
            </Box>
          </Trans>
        </Text>
        <form onSubmit={onSubmit}>
          <Button
            isSubmitButton
            text={t('simcard.confirmNewSimButton')}
            isLoading={loading}
            dottedShadow="none"
            colorScheme={color as MainColorType}
          />
        </form>
      </Box>
    );
  }

  const phoneNumber = formatTel(subscriptionId);
  const nationalId = formatNationalId(userNationalId);

  return (
    <Box
      marginTop={4}
      padding={{ sm: 3 }}
      dottedShadow="small"
      backgroundColor="white"
      borderColor="grey100"
      borderWidth="1px"
      borderStyle="solid"
      renderAs="form"
      onSubmit={onSubmit}
    >
      <Text variant="eyebrowMedium" color="pink">
        {t('simcard.newEsimEyebrow')}
      </Text>

      <Text variant="h6" paddingBottom={2}>
        {t('simcard.newEsimTitle')}
      </Text>

      <Text variant="pMediumRegular" paddingBottom={2}>
        <Trans i18nKey="stillingar:simcard.newSimcardDesciption">
          Þú ert að fara að breyta símkorti fyrir símanúmerið <strong>{{ phoneNumber }}</strong>.
          Skráður notandi á númerinu er <strong>{{ userName }}</strong> og kennitala
          <strong>{{ nationalId }}</strong>. Er þetta ekki örugglega rétt númer? Eftir þetta skref
          þarf að endurvirkja rafræn skilríki á nýja símkortinu. Er ekki örugglega búið að framvísa
          skilríkjum?
        </Trans>
      </Text>

      {!showIccidForm && (
        <Button
          text={t('simcard.confirmNewSimButton')}
          isLoading={loading}
          colorScheme={color as MainColorType}
          onClick={() => setShowIccidForm(true)}
        />
      )}

      {showIccidForm && (
        <Grid>
          <GridItem gridColumn={{ sm: 'span12', md: 'span6' }}>
            <Input
              name="Iccid"
              id="iccid"
              label={t('simcard.simcard')}
              value={iccid}
              onChange={(e) => setIccid(e.target.value)}
              autoComplete="off"
              message={message}
              minLength={18}
              maxLength={22}
              required
            />
          </GridItem>
          {isStaff && (
            <GridItem gridColumn={{ sm: 'span12', md: 'span2' }}>
              <Input
                name="SalesNumber"
                id="salesnumber"
                label={t('simcard.salesNumber')}
                value={salesNumber}
                onChange={(e) => setSalesNumber(e.target.value)}
                autoComplete="off"
                required
                maxLength={4}
                minLength={2}
              />
            </GridItem>
          )}
          <GridItem gridColumn={{ sm: 'span12', md: 'span4' }}>
            <Button
              isSubmitButton
              text={t('simcard.confirmNewSimButton')}
              isLoading={loading}
              icon="longArrowRight"
              colorScheme={color as MainColorType}
              dottedShadow="none"
            />
          </GridItem>
        </Grid>
      )}
    </Box>
  );
};

export default inject('authentication')(SimcardSettingsContainer);
